#pragma once
#include <Arduino.h>
#include <ArduinoJson.h>
#include <WebSocketsClient.h>
#include <initializer_list>
#include <utility>

// 1. 声明二维数组（与gain.h定义匹配，b对应第一个维度，c对应第二个维度）
extern const char* CHANNEL_MAP[2][16];

// 2. 声明外部变量（不变）
extern WebSocketsClient webSocket;
extern String WS_TARGET_ID;

// 3. 基础JSON发送函数（不变）
template <typename TDoc>
static inline bool _wsSend(const TDoc& doc) {
  String json;
  serializeJson(doc, json);
  Serial.println("发送消息: " + json);
  return webSocket.sendTXT(json);
}

// 4. 私聊发送函数（核心修改：content数组新增b字段）
static inline bool sendPrivateToId(const String& toId, const String& content) {
  if (!toId.length()) {
    Serial.println("[warn] 目标ID为空, 未发送");
    return false;
  }
  StaticJsonDocument<384> doc;
  doc["type"]    = "servo_control";  // 保持与目标格式一致
  doc["to"]      = toId;             // 目标ID（不变）
  doc["content"] = content;          // 核心：content为包含b/c/p的数组
  return _wsSend(doc);
}

// 5. 单条/多条发送（核心修改：添加b字段，b=MUX下标，c=内部通道）
static inline bool sendServoControl(std::initializer_list<std::pair<int, int>> items) {
  StaticJsonDocument<512> arrDoc;
  JsonArray arr = arrDoc.to<JsonArray>();

  for (auto& it : items) {
    JsonObject o = arr.createNestedObject();
    int total_ch = it.first;  // 总通道号（0~31，对应2个MUX×16通道）

    if (total_ch >= 0 && total_ch < 32) {
      uint8_t mux_idx = total_ch / 16;  // b字段：MUX下标（0或1）
      uint8_t ch = total_ch % 16;       // c字段：MUX内部通道（0~15）
      o["b"] = String(mux_idx);         // 新增b字段（字符串格式，与目标一致）
      o["c"] = String(ch);              // 修正c字段：直接用内部通道号（而非CHANNEL_MAP）
    } else {
      o["b"] = "0";
      o["c"] = "0";
    }
    o["p"] = it.second;  // 脉宽值（不变）
  }

  String content;
  serializeJson(arrDoc, content);
  return sendPrivateToId(WS_TARGET_ID, content);
}

// 6. 服务器控制模式发送（同上述修改：添加b字段）
static inline bool sendServoControlAsServerControl(std::initializer_list<std::pair<int, int>> items) {
  StaticJsonDocument<512> arrDoc;
  JsonArray arr = arrDoc.to<JsonArray>();

  for (auto& it : items) {
    JsonObject o = arr.createNestedObject();
    int total_ch = it.first;

    if (total_ch >= 0 && total_ch < 32) {
      uint8_t mux_idx = total_ch / 16;
      uint8_t ch = total_ch % 16;
      o["b"] = String(mux_idx);
      o["c"] = String(ch);
    } else {
      o["b"] = "0";
      o["c"] = "0";
    }
    o["p"] = it.second;
  }

  String content;
  serializeJson(arrDoc, content);
  StaticJsonDocument<384> doc;
  doc["type"]    = "servo_control";
  doc["content"] = content;
  return _wsSend(doc);
}

// 7. 32路批量发送（核心修改：删除CHANNEL_MAP依赖，直接生成b/c字段）
static inline bool sendServoControlN(const std::pair<int, int>* items, size_t n) {
  StaticJsonDocument<3072> doc;  
  doc["type"] = "servo_control";
  doc["to"]   = WS_TARGET_ID;

  StaticJsonDocument<2048> arrDoc;
  JsonArray arr = arrDoc.to<JsonArray>();

  for (size_t i = 0; i < n; ++i) {
    JsonObject o = arr.createNestedObject();
    int total_ch = items[i].first;  // 总通道号（0~31）

    if (total_ch >= 0 && total_ch < 32) {
      uint8_t mux_idx = total_ch / 16;  // b = MUX下标（0/1）
      uint8_t ch = total_ch % 16;       // c = 内部通道（0~15）
      o["b"] = String(mux_idx);         // 字符串格式，与目标一致
      o["c"] = String(ch);
    } else {
      o["b"] = "0";
      o["c"] = "0";
    }
    o["p"] = items[i].second;
  }

  String contentStr;
  serializeJson(arrDoc, contentStr);
  doc["content"] = contentStr;

  return _wsSend(doc);
}
